home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_include / ASM-I386 / ATOMIC.H < prev    next >
C/C++ Source or Header  |  1999-09-17  |  2KB  |  86 lines

  1. #ifndef __ARCH_I386_ATOMIC__
  2. #define __ARCH_I386_ATOMIC__
  3.  
  4. /*
  5.  * Atomic operations that C can't guarantee us.  Useful for
  6.  * resource counting etc..
  7.  */
  8.  
  9. #ifdef __SMP__
  10. #define LOCK "lock ; "
  11. #else
  12. #define LOCK ""
  13. #endif
  14.  
  15. /*
  16.  * Make sure gcc doesn't try to be clever and move things around
  17.  * on us. We need to use _exactly_ the address the user gave us,
  18.  * not some alias that contains the same information.
  19.  */
  20. #define __atomic_fool_gcc(x) (*(volatile struct { int a[100]; } *)x)
  21.  
  22. #ifdef __SMP__
  23. typedef struct { volatile int counter; } atomic_t;
  24. #else
  25. typedef struct { int counter; } atomic_t;
  26. #endif
  27.  
  28. #define ATOMIC_INIT(i)    { (i) }
  29.  
  30. #define atomic_read(v)        ((v)->counter)
  31. #define atomic_set(v,i)        (((v)->counter) = (i))
  32.  
  33. static __inline__ void atomic_add(int i, volatile atomic_t *v)
  34. {
  35.     __asm__ __volatile__(
  36.         LOCK "addl %1,%0"
  37.         :"=m" (__atomic_fool_gcc(v))
  38.         :"ir" (i), "m" (__atomic_fool_gcc(v)));
  39. }
  40.  
  41. static __inline__ void atomic_sub(int i, volatile atomic_t *v)
  42. {
  43.     __asm__ __volatile__(
  44.         LOCK "subl %1,%0"
  45.         :"=m" (__atomic_fool_gcc(v))
  46.         :"ir" (i), "m" (__atomic_fool_gcc(v)));
  47. }
  48.  
  49. static __inline__ void atomic_inc(volatile atomic_t *v)
  50. {
  51.     __asm__ __volatile__(
  52.         LOCK "incl %0"
  53.         :"=m" (__atomic_fool_gcc(v))
  54.         :"m" (__atomic_fool_gcc(v)));
  55. }
  56.  
  57. static __inline__ void atomic_dec(volatile atomic_t *v)
  58. {
  59.     __asm__ __volatile__(
  60.         LOCK "decl %0"
  61.         :"=m" (__atomic_fool_gcc(v))
  62.         :"m" (__atomic_fool_gcc(v)));
  63. }
  64.  
  65. static __inline__ int atomic_dec_and_test(volatile atomic_t *v)
  66. {
  67.     unsigned char c;
  68.  
  69.     __asm__ __volatile__(
  70.         LOCK "decl %0; sete %1"
  71.         :"=m" (__atomic_fool_gcc(v)), "=qm" (c)
  72.         :"m" (__atomic_fool_gcc(v)));
  73.     return c != 0;
  74. }
  75.  
  76. /* These are x86-specific, used by some header files */
  77. #define atomic_clear_mask(mask, addr) \
  78. __asm__ __volatile__(LOCK "andl %0,%1" \
  79. : : "r" (~(mask)),"m" (__atomic_fool_gcc(addr)) : "memory")
  80.  
  81. #define atomic_set_mask(mask, addr) \
  82. __asm__ __volatile__(LOCK "orl %0,%1" \
  83. : : "r" (mask),"m" (__atomic_fool_gcc(addr)) : "memory")
  84.  
  85. #endif
  86.